package com.strongbj.iot.devices.ru.response.task;

import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.strongbj.iot.devices.ru.response.entity.UInfoEntity;
import com.strongbj.iot.devices.ru.response.message.RUMQMessage;
import com.strongbj.iot.devices.ru.response.service.ICabinetService;
import com.strongbj.iot.mq.producer.TopicSender;

/**
 * RU1000设备关门后推送U位信息的任务处理
 * 
 * @author yuzhantao
 *
 */
@Service
@Lazy(false)
public class PushUInfoTask {
	private static Logger logger = LogManager.getLogger(PushUInfoTask.class.getName());

	private final static int U_MAX_COUNT = 43; // U位的数量
	private final static int SINGLE_U_SCAN_TIME = 1000; // 单个U位扫描的毫秒数
	private final static int WAITE_MILLISECOND = U_MAX_COUNT * SINGLE_U_SCAN_TIME + 10000;// 机柜关门后等待的时间，超过此毫秒后自动发送数据到mq
//	private final static String EMPTY_LABEL_ID = "00000000"; // 空标签ID
	@Autowired
	ICabinetService cabinetService;
	@Autowired
	TopicSender topicSender;

	/**
	 * 在机柜门关闭的时候推送数据
	 */
	@Scheduled(cron = "0/10 * * * * ?")
	public void pushDataAtDoorClose() {
		Collection<UInfoEntity> cabinetList = cabinetService.findAllCabinetInfoList();
		logger.info("#task 内存中的缓存结构---------------------------");
		logger.info("#task " + JSON.toJSONString(cabinetList));
		logger.info("#task ----------------------------------------");
//		for (int j = 0; j < cabinetList.size(); j++) {
//
//		}

		try {
			synchronized (cabinetList) {
				Iterator<UInfoEntity> it = cabinetList.iterator();
				while (it.hasNext()) {
					UInfoEntity cab = it.next();
					for (UInfoEntity.DevAddr dev : cab.getDevAddrList()) {
						// 如果开着门，不上传数据
						if (dev.getDoorState() == 1)
							continue;
						logger.debug("#task[" + dev.getDevAddrCode() + "] 已通过关门检测");
						// 如果扫描U位时间小于关门时间，不上传数据
						if (dev.getDoorStateUpdateTime().getTime() > dev.getCheckUpdateTime().getTime())
							continue;
						logger.debug("#task[" + dev.getDevAddrCode() + "] 已通过大于关门时间的检测");
						// 如果扫描U位时间没超过等待时间，不上传数据（防止多次反复开关扫描问题）
						logger.debug("#task[" + dev.getDevAddrCode() + "] 扫描后到当前时间"
								+ (System.currentTimeMillis() - dev.getCheckUpdateTime().getTime()) + "毫秒");
						if (isTimeout(dev.getCheckUpdateTime(), WAITE_MILLISECOND) == false)
							continue;
						logger.debug("#task[" + dev.getDevAddrCode() + "] 已通过扫描后超时等待时间的检测");
						// 判断扫描的U位是否全空
						boolean isAllEmtryOfU = true;
						for (UInfoEntity.UdevInfo u : dev.getUdevInfo()) {
							try {
								if (Integer.valueOf(u.getRfid()) != 0) {
									isAllEmtryOfU = false;
									break;
								}
							} catch (Exception e) {
								isAllEmtryOfU = false;
								break;
							}
						}
						
//						if (isAllEmtryOfU)
//							continue; // 如果U位全空，就不上传数据
						
						
						logger.debug("#task[" + dev.getDevAddrCode() + "] 已通过扫描非全空的检测");

						String json = this.uInfo2JsonString(cab);
						topicSender.send("RU", json);
						logger.info("#task->push " + json);
						logger.info("#task->push devAddrCode=" + dev.getDevAddrCode() + "  U位数量="
								+ dev.getUdevInfo().size());
						cabinetService.removeCabinetInfo(dev.getDevAddrCode());
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * U位信息转Json字符串
	 * 
	 * @param entity
	 * @return
	 */
	private String uInfo2JsonString(UInfoEntity entity) {
		RUMQMessage mes = new RUMQMessage();
		mes.setActioncode("reader003");
		mes.setGUID(String.valueOf(new Date().getTime()));
		mes.setRfidtype("RU1000");
		mes.setAwsPostdata(entity);
		return JSON.toJSONString(mes);
	}

	/**
	 * 指定时间是否超过秒数
	 * 
	 * @param updateTime
	 * @param timeoutMillisecond
	 * @return
	 */
	private boolean isTimeout(Date updateTime, int timeoutMillisecond) {
		return isTimeout(updateTime, new Date(), timeoutMillisecond);
	}

	private boolean isTimeout(Date startTime, Date endTime, int timeoutMillisecond) {
		if (endTime.getTime() - startTime.getTime() > timeoutMillisecond) {
			return true;
		} else {
			return false;
		}
	}
}
